#ifndef _UART_DRIVER_H
#define _UART_DRIVER_H

#include "core/drv.h"
#include "ringbuffer/ring_buffer.h"

typedef device_t uart_device_t;



typedef enum uart_event_type {
    UART_EVENT_DATA,
    UART_EVENT_TX_DONE,
    UART_EVENT_FIFO_OVERFLOW,
    UART_EVENT_PARITY_ERROR,
    UART_EVENT_FRAME_ERROR,
    UART_EVENT_BREAK_DETECTED,
    UART_EVENT_RX_TIMEOUT,
    // ...
} uart_event_type_t;

typedef enum uart_ctrl_cmd{
    UART_CTRL_CMD_NONE,
    UART_CTRL_CMD_SET_BAUDRATE,
    UART_CTRL_CMD_SET_DATABITS,
    UART_CTRL_CMD_SET_PARITY,
    UART_CTRL_CMD_SET_STOPBITS,
    UART_CTRL_CMD_SET_ISR_ENABLE,
    UART_CTRL_CMD_SET_ISR_DISABLE,
    UART_CTRL_CMD_FLOWCTRL,
    UART_CTRL_CMD_SET_EVENT_CB_ADD,
    UART_CTRL_CMD_SET_EVENT_CB_REMOVE,
    UART_CTRL_CMD_SET_LOWPOWER_ENTER,
    UART_CTRL_CMD_SET_LOWPOWER_EXIT,
}uart_ctrl_cmd_t;

typedef void (*uart_event_cb)(uart_device_t *dev, uart_event_type_t event, void *args,void *user_data);

#define UART_PARITY_IS_VALID(x)   ((x) == UART_DATA_PARITY_NONE || (x) == UART_DATA_PARITY_EVEN || (x) == UART_DATA_PARITY_ODD || (x) == UART_DATA_PARITY_MARK || (x) == UART_DATA_PARITY_SPACE)
#define UART_STOP_BITS_IS_VALID(x) ((x) == UART_STOP_BITS_1 || (x) == UART_STOP_BITS_1_5 || (x) == UART_STOP_BITS_2)
#define UART_DATA_BITS_IS_VALID(x) ((x) >= UART_DATA_BITS_5 && (x) <= UART_DATA_BITS_9)
#define UART_FLOW_CONTROL_IS_VALID(x) ((x) == UART_FLOW_CTRL_NONE || (x) == UART_FLOW_CTRL_RTS || (x) == UART_FLOW_CTRL_CTS || (x) == UART_FLOW_CTRL_RTS_CTS || (x) == UART_FLOW_CTRL_SOFTWARE)
//#define UART_MODE_IS_VALID(x) ((x) == UART_MODE_NORMAL || (x) == UART_MODE_LOOPBACK || (x) == UART_MODE_RS485)
#define UART_BAUDRATE_IS_VALID(x) ( \
    (x) == UART_BAUDRATE_1200    || (x) == UART_BAUDRATE_2400    || (x) == UART_BAUDRATE_4800   || \
    (x) == UART_BAUDRATE_9600    || (x) == UART_BAUDRATE_14400   || (x) == UART_BAUDRATE_19200  || \
    (x) == UART_BAUDRATE_28800   || (x) == UART_BAUDRATE_38400   || (x) == UART_BAUDRATE_57600  || \
    (x) == UART_BAUDRATE_76800   || (x) == UART_BAUDRATE_115200  || (x) == UART_BAUDRATE_128000 || \
    (x) == UART_BAUDRATE_230400  || (x) == UART_BAUDRATE_250000  || (x) == UART_BAUDRATE_460800 || \
    (x) == UART_BAUDRATE_500000  || (x) == UART_BAUDRATE_576000  || (x) == UART_BAUDRATE_921600 || \
    (x) == UART_BAUDRATE_1000000 || (x) == UART_BAUDRATE_1500000 || (x) == UART_BAUDRATE_2000000|| \
    (x) == UART_BAUDRATE_3000000 || (x) == UART_BAUDRATE_4000000)

#define UART_PORT_ENUM_ENTRY(n) UART_PORT_##n,
#define UART_PORT_ENUM_MIN UART_PORT_MIN
#define UART_PORT_ENUM_MAX UART_PORT_MAX 

typedef enum uart_port_map {
    UART_PORT_ENUM_ENTRY(NONE)
    UART_PORT_ENUM_ENTRY(0)
    UART_PORT_ENUM_ENTRY(1)
    UART_PORT_ENUM_ENTRY(2)
    UART_PORT_ENUM_ENTRY(3)
    UART_PORT_MIN = UART_PORT_NONE,
    UART_PORT_MAX = UART_PORT_3,
} uart_device_port_t;


typedef enum {
    UART_BAUDRATE_1200     = 1200,     /**< 1200 bps */
    UART_BAUDRATE_2400     = 2400,     /**< 2400 bps */
    UART_BAUDRATE_4800     = 4800,     /**< 4800 bps */
    UART_BAUDRATE_9600     = 9600,     /**< 9600 bps (common default) */
    UART_BAUDRATE_14400    = 14400,    /**< 14400 bps */
    UART_BAUDRATE_19200    = 19200,    /**< 19200 bps */
    UART_BAUDRATE_28800    = 28800,    /**< 28800 bps */
    UART_BAUDRATE_38400    = 38400,    /**< 38400 bps */
    UART_BAUDRATE_57600    = 57600,    /**< 57600 bps */
    UART_BAUDRATE_76800    = 76800,    /**< 76800 bps */
    UART_BAUDRATE_115200   = 115200,   /**< 115200 bps (most common) */
    UART_BAUDRATE_128000   = 128000,   /**< 128000 bps */
    UART_BAUDRATE_230400   = 230400,   /**< 230400 bps */
    UART_BAUDRATE_250000   = 250000,   /**< 250000 bps */
    UART_BAUDRATE_460800   = 460800,   /**< 460800 bps */
    UART_BAUDRATE_500000   = 500000,   /**< 500000 bps */
    UART_BAUDRATE_576000   = 576000,   /**< 576000 bps */
    UART_BAUDRATE_921600   = 921600,   /**< 921600 bps */
    UART_BAUDRATE_1000000  = 1000000,  /**< 1 Mbps */
    UART_BAUDRATE_1500000  = 1500000,  /**< 1.5 Mbps */
    UART_BAUDRATE_2000000  = 2000000,  /**< 2 Mbps */
    UART_BAUDRATE_3000000  = 3000000,  /**< 3 Mbps */
    UART_BAUDRATE_4000000  = 4000000,  /**< 4 Mbps */
    UART_BAUDRATE_MAX
} uart_device_baudrate_t;

typedef enum {
    UART_FLOW_CTRL_NONE = 0,  /**< No flow control */
    UART_FLOW_CTRL_RTS,       /**< Hardware RTS */
    UART_FLOW_CTRL_CTS,       /**< Hardware CTS */
    UART_FLOW_CTRL_RTS_CTS,   /**< Hardware RTS and CTS */
    UART_FLOW_CTRL_SOFTWARE   /**< Software flow control (XON/XOFF) */
} uart_device_flow_control_t;


typedef enum {
    UART_DATA_BITS_5 = 5,    /**< 5 data bits */
    UART_DATA_BITS_6 = 6,    /**< 6 data bits */
    UART_DATA_BITS_7 = 7,    /**< 7 data bits */
    UART_DATA_BITS_8 = 8,    /**< 8 data bits */
    UART_DATA_BITS_9 = 9     /**< 9 data bits */
} uart_device_data_bits_t;


typedef enum {
    UART_STOP_BITS_1 = 0,    /**< 1 stop bit */
    UART_STOP_BITS_1_5,      /**< 1.5 stop bits (usually only in 5-bit mode) */
    UART_STOP_BITS_2         /**< 2 stop bits */
} uart_device_stop_bits_t;


typedef enum {
    UART_DATA_PARITY_NONE = 0,    /**< No parity */
    UART_DATA_PARITY_EVEN,        /**< Even parity */
    UART_DATA_PARITY_ODD,         /**< Odd parity */
    UART_DATA_PARITY_MARK,        /**< Mark parity (parity bit always 1) */
    UART_DATA_PARITY_SPACE        /**< Space parity (parity bit always 0) */
} uart_device_parity_t;


typedef struct uart_data_config{
    uint32_t rx_fifo_size;
    uint32_t tx_fifo_size;
    ring_buffer_t rx_ringbuf;
    ring_buffer_t tx_ringbuf;
}uart_data_config_t;

typedef struct uart_device_config{
    uart_device_baudrate_t baudrate;
    uart_device_data_bits_t databits;
    uart_device_stop_bits_t stopbits;
    uart_device_parity_t parity;
    uart_device_flow_control_t flowctrl;
    uart_data_config_t data_cfg;
}uart_device_config_t;

typedef struct uart_event_cfg{
    void *user_data;
    uart_event_cb evt_cb;
}uart_event_cfg_t;

typedef struct uart_private_context{
    bool open_status;
    bool irq_enable_status;
    uart_device_port_t port;
    uart_device_t *dev;
    uart_device_config_t uart_cfg;
    uart_event_cfg_t evt;
    struct uart_private_context *next;
    bool is_busy;
}uart_private_context_t;

typedef struct uart_hal_driver_ops{
    int (*hal_uart_init)(uart_device_port_t port, uart_device_config_t *cfg);
    int (*hal_uart_deinit)(uart_device_port_t port);
    int (*hal_uart_isr_enable)(uart_device_port_t port);
    int (*hal_uart_isr_disable)(uart_device_port_t port);
    int (*hal_uart_lowpower_enter)(uart_device_port_t port);
    int (*hal_uart_lowpower_exit)(uart_device_port_t port);
    int (*hal_uart_transmit)(uart_device_port_t port, void *data, uint32_t len);
    int (*hal_uart_received)(uart_device_port_t port, void *data, uint32_t len);
}uart_hal_driver_ops_t;


typedef struct uart_driver_ops{
    // int (*uart_transmit)(uart_device_t *dev, void *data, uint32_t len);
    // int (*uart_received)(uart_device_t *dev, void *data, uint32_t len);
    int (*uart_isr_enable)(uart_device_t *dev);
    int (*uart_isr_disable)(uart_device_t *dev);
    int (*uart_event_handle_add)(uart_device_t *dev, uart_event_cb cb, void *user_data);
    int (*uart_event_handle_remove)(uart_device_t *dev);
    int (*uart_set_baudrate)(uart_device_t *dev, uart_device_baudrate_t baudrate);
    int (*uart_set_databits)(uart_device_t *dev, uart_device_data_bits_t databits);
    int (*uart_set_stopbits)(uart_device_t *dev, uart_device_stop_bits_t stopbits);
    int (*uart_set_parity)(uart_device_t *dev, uart_device_parity_t parity);
    int (*uart_set_flowctrl)(uart_device_t *dev, uart_device_flow_control_t flowctrl);
    int (*uart_set_lowpower_enter)(uart_device_t *dev);
    int (*uart_set_lowpower_exit)(uart_device_t *dev);
}uart_driver_ops_t;

EXTERN DEVICE_PUBLIC(driver_t) uart_device_driver;
EXTERN DEVICE_PUBLIC(void) uart_driver_transmit_handler(void);
EXTERN DEVICE_PUBLIC(void) uart_driver_isr_received_handler(uart_device_port_t uart_port, void *data, uint32_t len);

#endif
